#pragma once

#include <string>
#include <iostream>
#include <ctime>
#include <cstdlib>

/**
4．
Person 类保存人的名和姓。除构造函数外，它还有 Show(  )方法，用于显示名和姓。Gunslinger 类
以Person 类为虚基类派生而来，它包含一个Draw(  )成员，该方法返回一个double 值，表示枪手的拔枪时
间。这个类还包含一个int 成员，表示枪手枪上的刻痕数。最后，这个类还包含一个Show( )函数，用于显
示所有这些信息。 PokerPlayer 类以Person 类为虚基类派生而来。它包含一个Draw(  )成员，该函数返回一个1～52 的随
机数，用于表示扑克牌的值（也可以定义一个Card 类，其中包含花色和面值成员，然后让Draw(  )返回一
个Card 对象）。PokerPlayer 类使用Person 类的show(  )函数。BadDude(  )类从Gunslinger 和PokerPlayer 类
公有派生而来。它包含Gdraw( )成员（返回坏蛋拔枪的时间）和Cdraw( )成员（返回下一张扑克牌），另外
还有一个合适的Show( )函数。请定义这些类和方法以及其他必要的方法（如用于设置对象值的方法），并
使用一个类似于程序清单14.12 的简单程序对它们进行测试。
*/

class Person 
{
private:
    std::string first_name;
    std::string last_name;
public:
    virtual ~Person() = default;
    Person(){}
    Person(std::string fn,std::string ln):first_name(fn),last_name(ln){}
    virtual void Show() const {
        std::cout << "Person: " << first_name << " " << last_name << std::endl;
    }
};

class Gunslinger: virtual public Person
{
private:
    double draw_time;
    int notches;
public:
    Gunslinger(std::string fn,std::string ln,double dt,int nt):Person(fn,ln),draw_time(dt),notches(nt){}
    double Draw() const {return draw_time;}
    void Show() const {
        Person::Show();
        std::cout << " Notches: " << notches;
        std::cout << " Draw time: " << Draw() << std::endl;
    }
};

class Card
{
    enum CardVal {A,v2,v3,v4,v5,v6,v7,v8,v9,v10,J,Q,K};
    enum Suit {Diamonds,Hearts,Clubs,Spades};
    static const char* vals[13] ;
    static const char* suits[4];
    CardVal card_val;
    Suit suit;
public:
    Card(){}
    Card(CardVal cv,Suit s):card_val(cv),suit(s){}
    void Show() const {
        std::cout << "Card: "<< suits[suit] << " " << vals[card_val]<< std::endl;
    }
    Card random_card() {
        std::srand(std::time(nullptr));
        card_val = CardVal(std::rand() % 13) ;
        suit = Suit(std::rand() % 4);
        return *this;
    }
    friend std::ostream & operator << (std::ostream & os, const Card & c) {
        os << c.suits[c.suit] << " " << c.vals[c.card_val] ;
        return os;
    }
};

class PokerPlayer : virtual public Person 
{
public:
    PokerPlayer(const std::string & fname = "none", const std::string & lname = "none")
        : Person(fname, lname) {}
    
    Card Draw() const {  // 返回1-52的随机数
        return Card().random_card();
    }
    void Show() const {
        Person::Show();
    }
};

class BadDude : public Gunslinger, public PokerPlayer
{
public:
    BadDude(const std::string & fname = "none", const std::string & lname = "none", double dt = 0, int nt = 0)
        :Person(fname, lname), Gunslinger(fname, lname, dt, nt), PokerPlayer(fname, lname) {}
    
    void Show() const {
        Gunslinger::Show();
    }
    double Gdraw() const {return Gunslinger::Draw();}
    Card Cdraw() const {return PokerPlayer::Draw();}
};